﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.Issues.HeadmanNeedsToDeliverAHerdIssueBehavior
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.CharacterDevelopment;
using TaleWorlds.CampaignSystem.Conversation;
using TaleWorlds.CampaignSystem.MapEvents;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.ObjectSystem;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.Issues
{
  public class HeadmanNeedsToDeliverAHerdIssueBehavior : CampaignBehaviorBase
  {
    private const IssueBase.IssueFrequency HeadmanNeedsToDeliverAHerdIssueFrequency = IssueBase.IssueFrequency.VeryCommon;
    [SaveableField(216)]
    private HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssue _headmanNeedsToDeliverAHerdIssue;

    public override void RegisterEvents()
    {
      CampaignEvents.OnCheckForIssueEvent.AddNonSerializedListener((object) this, new Action<Hero>(this.OnCheckForIssue));
    }

    public override void SyncData(IDataStore dataStore)
    {
    }

    public void OnCheckForIssue(Hero hero)
    {
      if (this.ConditionsHold(hero))
        Campaign.Current.IssueManager.AddPotentialIssueData(hero, new PotentialIssueData(new PotentialIssueData.StartIssueDelegate(this.OnSelected), typeof (HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssue), IssueBase.IssueFrequency.VeryCommon));
      else
        Campaign.Current.IssueManager.AddPotentialIssueData(hero, new PotentialIssueData(typeof (HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssue), IssueBase.IssueFrequency.VeryCommon));
    }

    private bool ConditionsHold(Hero issueGiver)
    {
      return issueGiver.CurrentSettlement != null && issueGiver.CurrentSettlement.IsVillage && HeadmanNeedsToDeliverAHerdIssueBehavior.IsVillageSuitableForIssue(issueGiver.CurrentSettlement.Village) && (issueGiver.IsHeadman || issueGiver.IsRuralNotable) && issueGiver.CurrentSettlement.Village.Bound.Notables.Count > 0 && (double) issueGiver.CurrentSettlement.Village.Bound.Town.Security <= 60.0;
    }

    private static bool IsVillageSuitableForIssue(Village village)
    {
      if (village.Bound.IsCastle)
        return false;
      return village.VillageType == DefaultVillageTypes.BattanianHorseRanch || village.VillageType == DefaultVillageTypes.DesertHorseRanch || village.VillageType == DefaultVillageTypes.EuropeHorseRanch || village.VillageType == DefaultVillageTypes.SteppeHorseRanch || village.VillageType == DefaultVillageTypes.SturgianHorseRanch || village.VillageType == DefaultVillageTypes.VlandianHorseRanch || village.VillageType == DefaultVillageTypes.CattleRange || village.VillageType == DefaultVillageTypes.SheepFarm || village.VillageType == DefaultVillageTypes.HogFarm;
    }

    private IssueBase OnSelected(in PotentialIssueData pid, Hero issueOwner)
    {
      this._headmanNeedsToDeliverAHerdIssue = new HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssue(issueOwner);
      return (IssueBase) this._headmanNeedsToDeliverAHerdIssue;
    }

    public class HeadmanNeedsToDeliverAHerdIssue : IssueBase
    {
      private const float MaxDistanceForSettlementSelection = 250f;
      private const float MinDistanceForSettlementSelection = 100f;
      private const int IssueDuration = 30;
      private const int QuestTimeLimit = 30;
      private const int AlternativeSolutionTroopTierRequirement = 2;
      private const int RequiredSkillForSendingCompanion = 120;
      [CachedData]
      private readonly MBList<string> _possibleHerdTypes;
      [SaveableField(10)]
      private Settlement _targetSettlement;
      [SaveableField(20)]
      private Hero _targetHero;
      [SaveableField(30)]
      private ItemObject _herdTypeToDeliver;

      internal static void AutoGeneratedStaticCollectObjectsHeadmanNeedsToDeliverAHerdIssue(
        object o,
        List<object> collectedObjects)
      {
        ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
        collectedObjects.Add((object) this._targetSettlement);
        collectedObjects.Add((object) this._targetHero);
        collectedObjects.Add((object) this._herdTypeToDeliver);
      }

      internal static object AutoGeneratedGetMemberValue_targetSettlement(object o)
      {
        return (object) ((HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssue) o)._targetSettlement;
      }

      internal static object AutoGeneratedGetMemberValue_targetHero(object o)
      {
        return (object) ((HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssue) o)._targetHero;
      }

      internal static object AutoGeneratedGetMemberValue_herdTypeToDeliver(object o)
      {
        return (object) ((HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssue) o)._herdTypeToDeliver;
      }

      public override IssueBase.AlternativeSolutionScaleFlag AlternativeSolutionScaleFlags
      {
        get => IssueBase.AlternativeSolutionScaleFlag.Duration;
      }

      private int AnimalCountToDeliver
      {
        get
        {
          return (int) MathF.Clamp((float) MathF.Round(5000f * this.IssueDifficultyMultiplier / (float) this._herdTypeToDeliver.Value), 10f, 75f);
        }
      }

      public override int AlternativeSolutionBaseNeededMenCount
      {
        get => 6 + MathF.Ceiling(14f * this.IssueDifficultyMultiplier);
      }

      protected override int AlternativeSolutionBaseDurationInDaysInternal
      {
        get => 5 + MathF.Ceiling(5f * this.IssueDifficultyMultiplier);
      }

      protected override int RewardGold
      {
        get
        {
          return 300 + (int) ((double) this._herdTypeToDeliver.Value * 0.75 * (double) this.AnimalCountToDeliver);
        }
      }

      public override TextObject Description
      {
        get
        {
          TextObject description = new TextObject("{=kDIi3bLN}The village needs someone to take a herd to {TARGET_SETTLEMENT}.");
          description.SetTextVariable("TARGET_SETTLEMENT", this._targetSettlement.EncyclopediaLinkWithName);
          return description;
        }
      }

      public override TextObject IssueBriefByIssueGiver
      {
        get
        {
          TextObject briefByIssueGiver = new TextObject("{=7H4HQNvF}Yes. Some of the families in this village need to raise a bit of money. [if:convo_calm_friendly][ib:normal2]They've put together a herd of {ANIMAL_COUNT_TO_DELIVER} {.%}{?ANIMAL_COUNT_TO_DELIVER > 1}{PLURAL(HERD_TYPE_TO_DELIVER)}{?}{HERD_TYPE_TO_DELIVER}{\\?}{.%} to sell in {TARGET_SETTLEMENT}, but with all the banditry on the roads, they can't drive it there on their own. We're not merchants or landowners. We can't afford any losses.");
          if (this.IssueOwner.CharacterObject.GetPersona() == DefaultTraits.PersonaCurt)
            briefByIssueGiver = new TextObject("{=6kJ31qut}Yeah, well, some people here are a bit short of money these days. [if:convo_calm_friendly][ib:normal]They've put together a herd of {ANIMAL_COUNT_TO_DELIVER} {.%}{?ANIMAL_COUNT_TO_DELIVER > 1}{PLURAL(HERD_TYPE_TO_DELIVER)}{?}{HERD_TYPE_TO_DELIVER}{\\?}{.%} to sell in {TARGET_SETTLEMENT}. But they're poor folks. Not really fighters, and they can't afford to hire guards. If they go there by themselves they'd be sitting ducks for any bandits.");
          briefByIssueGiver.SetTextVariable("TARGET_SETTLEMENT", this._targetSettlement.EncyclopediaLinkWithName);
          briefByIssueGiver.SetTextVariable("ANIMAL_COUNT_TO_DELIVER", this.AnimalCountToDeliver);
          briefByIssueGiver.SetTextVariable("HERD_TYPE_TO_DELIVER", this._herdTypeToDeliver.Name);
          return briefByIssueGiver;
        }
      }

      public override TextObject IssueAcceptByPlayer
      {
        get => new TextObject("{=lmJYF6pQ}Tell me how I can help.");
      }

      public override TextObject IssueQuestSolutionExplanationByIssueGiver
      {
        get
        {
          TextObject parent = new TextObject("{=VbRyXBsv}If you're going in the direction of {TARGET_SETTLEMENT}, you can perhaps take our herd there to {TARGET_HERO.LINK}. I am willing to pay {REWARD_AMOUNT}{GOLD_ICON} if you deliver them safe and sound.[if:convo_calm_friendly][ib:normal]");
          parent.SetTextVariable("TARGET_SETTLEMENT", this._targetSettlement.EncyclopediaLinkWithName);
          parent.SetTextVariable("REWARD_AMOUNT", this.RewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          StringHelpers.SetCharacterProperties("TARGET_HERO", this._targetHero.CharacterObject, parent);
          return parent;
        }
      }

      public override TextObject IssueAlternativeSolutionExplanationByIssueGiver
      {
        get
        {
          TextObject explanationByIssueGiver = new TextObject("{=CqmoyrHH}You can assign a companion with {REQUIRED_SOLDIERS} men, they will be enough too. Both ways works fine for us. I promise if you or your men manage to deliver the herd safely, I will pay you {REWARD}{GOLD_ICON}. So what do you say?[if:convo_nonchalant]");
          explanationByIssueGiver.SetTextVariable("REQUIRED_SOLDIERS", this.GetTotalAlternativeSolutionNeededMenCount());
          explanationByIssueGiver.SetTextVariable("REWARD", this.RewardGold);
          explanationByIssueGiver.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return explanationByIssueGiver;
        }
      }

      public override TextObject IssueQuestSolutionAcceptByPlayer
      {
        get
        {
          TextObject parent = new TextObject("{=MJdVfS4z}Don't worry. I will deliver your {ANIMAL_COUNT_TO_DELIVER} {.%}{?ANIMAL_COUNT_TO_DELIVER > 1}{PLURAL(HERD_TYPE_TO_DELIVER)}{?}{HERD_TYPE_TO_DELIVER}{\\?}{.%} personally to {TARGET_HERO.LINK} in {TARGET_SETTLEMENT}.");
          parent.SetTextVariable("TARGET_SETTLEMENT", this._targetSettlement.Name);
          parent.SetTextVariable("ANIMAL_COUNT_TO_DELIVER", this.AnimalCountToDeliver);
          parent.SetTextVariable("HERD_TYPE_TO_DELIVER", this._herdTypeToDeliver.Name);
          StringHelpers.SetCharacterProperties("TARGET_HERO", this._targetHero.CharacterObject, parent);
          return parent;
        }
      }

      public override TextObject IssueAlternativeSolutionAcceptByPlayer
      {
        get
        {
          TextObject solutionAcceptByPlayer = new TextObject("{=k8W02aj9}I will assign a companion with {NEEDED_MEN_COUNT} of my men to deliver {ANIMAL_COUNT_TO_DELIVER} {.%}{?ANIMAL_COUNT_TO_DELIVER > 1}{PLURAL(HERD_TYPE_TO_DELIVER)}{?}{HERD_TYPE_TO_DELIVER}{\\?}{.%} safely.");
          solutionAcceptByPlayer.SetTextVariable("NEEDED_MEN_COUNT", this.GetTotalAlternativeSolutionNeededMenCount());
          solutionAcceptByPlayer.SetTextVariable("ANIMAL_COUNT_TO_DELIVER", this.AnimalCountToDeliver);
          solutionAcceptByPlayer.SetTextVariable("HERD_TYPE_TO_DELIVER", this._herdTypeToDeliver.Name);
          return solutionAcceptByPlayer;
        }
      }

      public override TextObject IssueDiscussAlternativeSolution
      {
        get
        {
          TextObject alternativeSolution = new TextObject("{=mwpY5Ylb}I am still waiting for news from {TARGET_SETTLEMENT}. Once again, I appreciate that you could spare the men to do this.[if:convo_calm_friendly]");
          alternativeSolution.SetTextVariable("TARGET_SETTLEMENT", this._targetSettlement.Name);
          return alternativeSolution;
        }
      }

      public override TextObject IssueAlternativeSolutionResponseByIssueGiver
      {
        get
        {
          TextObject parent = new TextObject("{=BJxJwCc5}Thank you, {?PLAYER.GENDER}madam{?}sir{\\?}. Any brigands would be most unwise to tangle with you.");
          if (this.IssueOwner.CharacterObject.GetPersona() == DefaultTraits.PersonaCurt)
            parent = new TextObject("{=muE5fcOf}Good. Anyone gives you trouble... Well, you look like you could handle them.");
          StringHelpers.SetCharacterProperties("PLAYER", CharacterObject.PlayerCharacter, parent);
          return parent;
        }
      }

      protected override TextObject AlternativeSolutionStartLog
      {
        get
        {
          TextObject parent = new TextObject("{=m2h6zMp7}{ISSUE_GIVER.LINK}, the headman from {SETTLEMENT}, has asked you to deliver some of the village's livestock to {SETTLEMENT_TARGET}. The villagers can't afford their own guards and also can't afford any losses. {ISSUE_GIVER.LINK} offers {REWARD_AMOUNT}{GOLD_ICON} for the herd's delivery. You sent {COMPANION.LINK} with {NEEDED_MEN_COUNT} of your men to protect the herd. They should return to you with news of their success in {RETURN_DAYS} days.");
          StringHelpers.SetCharacterProperties("ISSUE_GIVER", this.IssueOwner.CharacterObject, parent);
          StringHelpers.SetCharacterProperties("COMPANION", this.AlternativeSolutionHero.CharacterObject, parent);
          parent.SetTextVariable("SETTLEMENT", this.IssueOwner.CurrentSettlement.EncyclopediaLinkWithName);
          parent.SetTextVariable("SETTLEMENT_TARGET", this._targetSettlement.Name);
          parent.SetTextVariable("NEEDED_MEN_COUNT", this.AlternativeSolutionSentTroops.TotalManCount - 1);
          parent.SetTextVariable("RETURN_DAYS", this.GetTotalAlternativeSolutionDurationInDays());
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          parent.SetTextVariable("REWARD_AMOUNT", this.RewardGold);
          return parent;
        }
      }

      public override bool IsThereAlternativeSolution => true;

      public override bool IsThereLordSolution => false;

      public override TextObject IssueAsRumorInSettlement
      {
        get
        {
          TextObject parent = new TextObject("{=cvZH3cI1}I hope {QUEST_GIVER.NAME} has a plan to get that herd to market.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.IssueOwner.CharacterObject, parent);
          return parent;
        }
      }

      protected override int CompanionSkillRewardXP
      {
        get => (int) (500.0 + 700.0 * (double) this.IssueDifficultyMultiplier);
      }

      public override TextObject Title
      {
        get
        {
          TextObject title = new TextObject("{=KhUkmIrH}Deliver the herd to {TARGET_SETTLEMENT}");
          title.SetTextVariable("TARGET_SETTLEMENT", this._targetSettlement.Name);
          return title;
        }
      }

      public HeadmanNeedsToDeliverAHerdIssue(Hero issueOwner)
      {
        MBList<string> mbList = new MBList<string>();
        mbList.Add("sheep");
        mbList.Add("cow");
        mbList.Add("hog");
        this._possibleHerdTypes = mbList;
        // ISSUE: explicit constructor call
        base.\u002Ector(issueOwner, CampaignTime.DaysFromNow(30f));
        HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssue deliverAherdIssue = this;
        float distance;
        this._targetSettlement = SettlementHelper.FindRandomSettlement((Func<Settlement, bool>) (x => x.IsTown && x.Notables.Any<Hero>((Func<Hero, bool>) (y => y.CanHaveQuestsOrIssues())) && !x.MapFaction.IsAtWarWith(issueOwner.MapFaction) && !Campaign.Current.Models.MapDistanceModel.GetDistance(x, deliverAherdIssue.IssueSettlement, 100f, out distance) && Campaign.Current.Models.MapDistanceModel.GetDistance(x, deliverAherdIssue.IssueSettlement, 250f, out distance))) ?? this.IssueSettlement.Village.Bound;
        this._herdTypeToDeliver = Campaign.Current.ObjectManager.GetObject<ItemObject>(this._possibleHerdTypes.GetRandomElement<string>());
        if (this._targetSettlement == null)
          return;
        this._targetHero = this._targetSettlement.Notables.GetRandomElementWithPredicate<Hero>((Func<Hero, bool>) (x => x.CanHaveQuestsOrIssues())) ?? this._targetSettlement.Notables.GetRandomElement<Hero>();
      }

      protected override float GetIssueEffectAmountInternal(IssueEffect issueEffect)
      {
        return issueEffect == DefaultIssueEffects.SettlementProsperity ? -0.2f : 0.0f;
      }

      public override (SkillObject, int) GetAlternativeSolutionSkill(Hero hero)
      {
        return (hero.GetSkillValue(DefaultSkills.Riding) >= hero.GetSkillValue(DefaultSkills.Scouting) ? DefaultSkills.Riding : DefaultSkills.Scouting, 120);
      }

      public override bool DoTroopsSatisfyAlternativeSolution(
        TroopRoster troopRoster,
        out TextObject explanation)
      {
        explanation = TextObject.Empty;
        return QuestHelper.CheckRosterForAlternativeSolution(troopRoster, this.GetTotalAlternativeSolutionNeededMenCount(), ref explanation, 2);
      }

      public override bool IsTroopTypeNeededByAlternativeSolution(CharacterObject character)
      {
        return character.Tier >= 2;
      }

      public override bool IssueStayAliveConditions()
      {
        return !this.IssueOwner.CurrentSettlement.IsRaided && !this.IssueOwner.CurrentSettlement.IsUnderRaid && this._targetHero.IsActive && (double) this.IssueOwner.CurrentSettlement.Village.Bound.Town.Security <= 70.0;
      }

      protected override void CompleteIssueWithTimedOutConsequences()
      {
      }

      public override bool AlternativeSolutionCondition(out TextObject explanation)
      {
        explanation = TextObject.Empty;
        return QuestHelper.CheckRosterForAlternativeSolution(MobileParty.MainParty.MemberRoster, this.GetTotalAlternativeSolutionNeededMenCount(), ref explanation, 2);
      }

      protected override void AlternativeSolutionEndWithSuccessConsequence()
      {
        this.ApplySuccessRewards(this.IssueOwner);
      }

      private void ApplySuccessRewards(Hero issueGiver)
      {
        issueGiver.AddPower(5f);
        this.RelationshipChangeWithIssueOwner = 5;
        issueGiver.CurrentSettlement.Village.Hearth += 50f;
      }

      protected override void OnGameLoad()
      {
      }

      protected override void HourlyTick()
      {
      }

      protected override QuestBase GenerateIssueQuest(string questId)
      {
        return (QuestBase) new HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssueQuest(questId, this.IssueOwner, CampaignTime.DaysFromNow(30f), this.AnimalCountToDeliver, this._herdTypeToDeliver, this._targetSettlement, this.RewardGold, this._targetHero);
      }

      public override IssueBase.IssueFrequency GetFrequency()
      {
        return IssueBase.IssueFrequency.VeryCommon;
      }

      protected override bool CanPlayerTakeQuestConditions(
        Hero issueGiver,
        out IssueBase.PreconditionFlags flag,
        out Hero relationHero,
        out SkillObject skill)
      {
        flag = IssueBase.PreconditionFlags.None;
        relationHero = (Hero) null;
        skill = (SkillObject) null;
        if ((double) issueGiver.GetRelationWithPlayer() < -10.0)
        {
          flag |= IssueBase.PreconditionFlags.Relation;
          relationHero = issueGiver;
        }
        if (issueGiver.CurrentSettlement.MapFaction.IsAtWarWith(Hero.MainHero.MapFaction))
          flag |= IssueBase.PreconditionFlags.AtWar;
        return flag == IssueBase.PreconditionFlags.None;
      }
    }

    public class HeadmanNeedsToDeliverAHerdIssueQuest : QuestBase
    {
      [SaveableField(10)]
      private readonly Settlement _targetSettlement;
      [SaveableField(20)]
      private readonly Hero _targetHero;
      [SaveableField(30)]
      private readonly ItemObject _herdTypeToDeliver;
      [SaveableField(40)]
      private readonly int _animalCountToDeliver;
      [SaveableField(70)]
      private int _rewardGold;
      [SaveableField(215)]
      private JournalLog _playerStartsQuestLog;

      internal static void AutoGeneratedStaticCollectObjectsHeadmanNeedsToDeliverAHerdIssueQuest(
        object o,
        List<object> collectedObjects)
      {
        ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
        collectedObjects.Add((object) this._targetSettlement);
        collectedObjects.Add((object) this._targetHero);
        collectedObjects.Add((object) this._herdTypeToDeliver);
        collectedObjects.Add((object) this._playerStartsQuestLog);
      }

      internal static object AutoGeneratedGetMemberValue_targetSettlement(object o)
      {
        return (object) ((HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssueQuest) o)._targetSettlement;
      }

      internal static object AutoGeneratedGetMemberValue_targetHero(object o)
      {
        return (object) ((HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssueQuest) o)._targetHero;
      }

      internal static object AutoGeneratedGetMemberValue_herdTypeToDeliver(object o)
      {
        return (object) ((HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssueQuest) o)._herdTypeToDeliver;
      }

      internal static object AutoGeneratedGetMemberValue_animalCountToDeliver(object o)
      {
        return (object) ((HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssueQuest) o)._animalCountToDeliver;
      }

      internal static object AutoGeneratedGetMemberValue_rewardGold(object o)
      {
        return (object) ((HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssueQuest) o)._rewardGold;
      }

      internal static object AutoGeneratedGetMemberValue_playerStartsQuestLog(object o)
      {
        return (object) ((HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssueQuest) o)._playerStartsQuestLog;
      }

      public override sealed TextObject Title
      {
        get
        {
          TextObject title = new TextObject("{=KhUkmIrH}Deliver the herd to {TARGET_SETTLEMENT}");
          title.SetTextVariable("TARGET_SETTLEMENT", this._targetSettlement.Name);
          return title;
        }
      }

      public override bool IsRemainingTimeHidden => false;

      private TextObject _playerStartsQuestLogText
      {
        get
        {
          TextObject parent = new TextObject("{=wsGDDXPN}{QUEST_GIVER.LINK}, the headman from {QUEST_GIVER_SETTLEMENT} has asked you to deliver {ANIMAL_COUNT_TO_DELIVER} {.%}{?ANIMAL_COUNT_TO_DELIVER > 1}{PLURAL(HERD_TYPE_TO_DELIVER)}{?}{HERD_TYPE_TO_DELIVER}{\\?}{.%} to {TARGET_HERO.LINK} in {TARGET_SETTLEMENT}. {?QUEST_GIVER.GENDER}She{?}He{\\?} fears such a large herd will attract attention from the brigands on the way. {QUEST_GIVER.LINK} offers {REWARD_AMOUNT}{GOLD_ICON} for the herd's delivery.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          StringHelpers.SetCharacterProperties("TARGET_HERO", this._targetHero.CharacterObject, parent);
          parent.SetTextVariable("QUEST_GIVER_SETTLEMENT", this.QuestGiver.CurrentSettlement.EncyclopediaLinkWithName);
          parent.SetTextVariable("ANIMAL_COUNT_TO_DELIVER", this._animalCountToDeliver);
          parent.SetTextVariable("TARGET_SETTLEMENT", this._targetSettlement.EncyclopediaLinkWithName);
          parent.SetTextVariable("HERD_TYPE_TO_DELIVER", this._herdTypeToDeliver.Name);
          parent.SetTextVariable("REWARD_AMOUNT", this._rewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return parent;
        }
      }

      private TextObject _successQuestLogText
      {
        get
        {
          TextObject parent = new TextObject("{=6IKKFH3A}You have received a message and a large purse from {QUEST_GIVER.LINK}. The missive reads: ”The herd is safe. Thank you, and please accept these {REWARD}{GOLD_ICON} with our gratitude.”.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("REWARD", this._rewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return parent;
        }
      }

      private TextObject _failByTimeOutQuestLogText
      {
        get
        {
          TextObject parent = new TextObject("{=hhrRnSvr}You failed to deliver the herd in time, as {QUEST_GIVER.LINK} has asked of you. The shepherds and the herd left you.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return parent;
        }
      }

      private TextObject _failByRejectQuestLogText
      {
        get
        {
          TextObject parent = new TextObject("{=MjwNHtQd}You rejected to deliver the herd, as {QUEST_GIVER.LINK} has asked of you. The shepherds have left you.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return parent;
        }
      }

      private TextObject _questCanceledWarDeclaredLog
      {
        get
        {
          TextObject parent = new TextObject("{=vW6kBki9}Your clan is now at war with {QUEST_GIVER.LINK}'s realm. Your agreement with {QUEST_GIVER.LINK} is canceled.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      private TextObject _playerDeclaredWarQuestLogText
      {
        get
        {
          TextObject parent = new TextObject("{=bqeWVVEE}Your actions have started a war with {QUEST_GIVER.LINK}'s faction. {?QUEST_GIVER.GENDER}She{?}He{\\?} cancels your agreement and the quest is a failure.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      public HeadmanNeedsToDeliverAHerdIssueQuest(
        string questId,
        Hero questGiver,
        CampaignTime duration,
        int animalCountToDeliver,
        ItemObject herdTypeToDeliver,
        Settlement targetSettlement,
        int rewardGold,
        Hero targetHero)
        : base(questId, questGiver, duration, rewardGold)
      {
        this._animalCountToDeliver = animalCountToDeliver;
        this._herdTypeToDeliver = herdTypeToDeliver;
        this._targetSettlement = targetSettlement;
        this._rewardGold = rewardGold;
        this._targetHero = targetHero;
        this.SetDialogs();
        this.InitializeQuestOnCreation();
      }

      protected override void SetDialogs()
      {
        TextObject textObject = new TextObject("{=iUQuwAZY}Thank you, {?PLAYER.GENDER}madam{?}sir{\\?}. The village will be grateful to you. Good luck.");
        StringHelpers.SetCharacterProperties("PLAYER", CharacterObject.PlayerCharacter, textObject);
        this.OfferDialogFlow = DialogFlow.CreateDialogFlow("issue_classic_quest_start").NpcLine(textObject).Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).Consequence(new ConversationSentence.OnConsequenceDelegate(this.QuestAcceptedConsequences)).CloseDialog();
        this.DiscussDialogFlow = DialogFlow.CreateDialogFlow("quest_discuss").NpcLine(new TextObject("{=zB6elkn1}The herd is ready to depart.")).Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).BeginPlayerOptions().PlayerOption(new TextObject("{=8tBET7S5}Good. We will be heading out soon.")).NpcLine(new TextObject("{=iAGx49nO}Good to hear that! Safe journeys.[if:convo_approving]")).CloseDialog().PlayerOption(new TextObject("{=EOaOlh39}In due time. Let's not be too hasty.")).NpcLine(new TextObject("{=79Te4duG}As you wish.[if:convo_normal][ib:demure]")).CloseDialog().EndPlayerOptions().CloseDialog();
      }

      private void QuestAcceptedConsequences()
      {
        this.StartQuest();
        this._playerStartsQuestLog = this.AddLog(this._playerStartsQuestLogText);
        this.AddHerdAndShepherdsToMainParty();
        this.AddTrackedObject((ITrackableCampaignObject) this._targetSettlement);
        this.AddTrackedObject((ITrackableCampaignObject) this._targetHero);
        Campaign.Current.ConversationManager.AddDialogFlow(this.GetDeliveryDialogFlow(), (object) this);
      }

      protected override void OnCompleteWithSuccess()
      {
        this.QuestGiver.AddPower(5f);
        this.RelationshipChangeWithQuestGiver = 5;
        TraitLevelingHelper.OnIssueSolvedThroughQuest(this.QuestGiver, new Tuple<TraitObject, int>[1]
        {
          new Tuple<TraitObject, int>(DefaultTraits.Honor, 30)
        });
        this.QuestGiver.CurrentSettlement.Village.Hearth += 50f;
        this._targetSettlement.Town.Prosperity += 50f;
        int itemCountOnPlayer = this.GetAvailableRequestedItemCountOnPlayer(this._herdTypeToDeliver);
        int number = itemCountOnPlayer > this._animalCountToDeliver ? this._animalCountToDeliver : itemCountOnPlayer;
        foreach (ItemRosterElement itemRosterElement in MobileParty.MainParty.ItemRoster)
        {
          if (itemRosterElement.EquipmentElement.Item == this._herdTypeToDeliver)
          {
            int amount = itemRosterElement.Amount;
            if (amount < number)
            {
              number -= amount;
              PartyBase.MainParty.ItemRoster.AddToCounts(itemRosterElement.EquipmentElement, -amount);
              this._targetSettlement.ItemRoster.AddToCounts(itemRosterElement.EquipmentElement, amount);
            }
            else
            {
              PartyBase.MainParty.ItemRoster.AddToCounts(itemRosterElement.EquipmentElement, -number);
              this._targetSettlement.ItemRoster.AddToCounts(itemRosterElement.EquipmentElement, number);
              break;
            }
          }
        }
        GiveGoldAction.ApplyForQuestBetweenCharacters(this.QuestGiver, Hero.MainHero, this._rewardGold);
        this.AddLog(this._successQuestLogText);
      }

      protected override void OnFinalize()
      {
        this.RemoveTrackedObject((ITrackableCampaignObject) this._targetSettlement);
        this.RemoveTrackedObject((ITrackableCampaignObject) this._targetHero);
      }

      private DialogFlow GetDeliveryDialogFlow()
      {
        TextObject textObject1 = new TextObject("{=8nwZXNTk}About the task {QUEST_GIVER.LINK} gave me...");
        StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, textObject1);
        TextObject textObject2 = new TextObject("{=kwJBLl00}Yes {?PLAYER.GENDER}madam{?}sir{\\?}. Our mutual friend {QUEST_GIVER.LINK} sent word to us. {?QUEST_GIVER.GENDER}She{?}He{\\?} told us to expect you with {?QUEST_GIVER.GENDER}her{?}his{\\?} {HERD_AMOUNT} {.%}{?HERD_AMOUNT > 1}{PLURAL(HERD_TYPE)}{?}{HERD_TYPE}{\\?}{.%}.");
        TextObject npcText1 = new TextObject("{=vXCg3OYx}So, have you brought them?[if:convo_undecided_open]");
        textObject2.SetTextVariable("HERD_AMOUNT", this._animalCountToDeliver);
        textObject2.SetTextVariable("HERD_TYPE", this._herdTypeToDeliver.Name);
        StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, textObject2);
        StringHelpers.SetCharacterProperties("PLAYER", CharacterObject.PlayerCharacter, textObject2);
        TextObject text1 = new TextObject("{=wmZYHGb9}I brought {HERD_AMOUNT} {.%}{?HERD_AMOUNT > 1}{PLURAL(HERD_TYPE)}{?}{HERD_TYPE}{\\?}{.%} as we agreed.");
        text1.SetTextVariable("HERD_AMOUNT", this._animalCountToDeliver);
        text1.SetTextVariable("HERD_TYPE", this._herdTypeToDeliver.Name);
        TextObject textObject3 = new TextObject("{=VkUMPAfR}Thank you for your help. {QUEST_GIVER.LINK} will send your reward as soon as possible.[if:convo_calm_friendly][ib:demure]");
        StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, textObject3);
        TextObject text2 = new TextObject("{=1s54uxsA}Sorry. I don't have any animals for you this time.");
        TextObject npcText2 = new TextObject("{=1dUVrgQ8}I just hope you can deliver the herd soon.");
        TextObject text3 = new TextObject("{=HFZisEnI}I'm going to keep that herd for myself.");
        TextObject textObject4 = new TextObject("{=LpfQYLQo}What? That's straight-up theft. I guarantee you {QUEST_GIVER.LINK} will hear about this![if:convo_annoyed][ib:aggressive]");
        StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, textObject4);
        return DialogFlow.CreateDialogFlow("hero_main_options", 125).PlayerLine(textObject1).Condition((ConversationSentence.OnConditionDelegate) (() => Settlement.CurrentSettlement == this._targetSettlement && CharacterObject.OneToOneConversationCharacter.IsHero && CharacterObject.OneToOneConversationCharacter.HeroObject == this._targetHero)).NpcLine(textObject2).NpcLine(npcText1).BeginPlayerOptions().PlayerOption(text1).Condition((ConversationSentence.OnConditionDelegate) (() =>
        {
          int itemCountOnPlayer = this.GetAvailableRequestedItemCountOnPlayer(this._herdTypeToDeliver);
          Campaign.Current.ConversationManager.GetCurrentDialogLine().SetTextVariable("HERD_AMOUNT", this._animalCountToDeliver);
          Campaign.Current.ConversationManager.GetCurrentDialogLine().SetTextVariable("HERD_TYPE", this._herdTypeToDeliver.Name);
          int animalCountToDeliver = this._animalCountToDeliver;
          return itemCountOnPlayer >= animalCountToDeliver;
        })).NpcLine(textObject3).Consequence(new ConversationSentence.OnConsequenceDelegate(this.DeliverHerdOnConsequence)).CloseDialog().PlayerOption(text3).NpcLine(textObject4).Consequence(new ConversationSentence.OnConsequenceDelegate(this.DeliverHerdRejectOnConsequence)).CloseDialog().PlayerOption(text2).NpcLine(npcText2).CloseDialog().EndPlayerOptions().CloseDialog();
      }

      private void DeliverHerdRejectOnConsequence()
      {
        ChangeCrimeRatingAction.Apply(this.QuestGiver.CurrentSettlement.MapFaction, 20f);
        this.CompleteQuestWithFail();
      }

      private void DeliverHerdOnConsequence() => this.CompleteQuestWithSuccess();

      private int GetAvailableRequestedItemCountOnPlayer(ItemObject item)
      {
        int itemCountOnPlayer = 0;
        foreach (ItemRosterElement itemRosterElement in PartyBase.MainParty.ItemRoster)
        {
          if (itemRosterElement.EquipmentElement.Item == item)
            itemCountOnPlayer += itemRosterElement.Amount;
        }
        return itemCountOnPlayer;
      }

      public override void OnCanceled()
      {
        int itemCountOnPlayer = this.GetAvailableRequestedItemCountOnPlayer(this._herdTypeToDeliver);
        PartyBase.MainParty.ItemRoster.AddToCounts(this._herdTypeToDeliver, itemCountOnPlayer > this._animalCountToDeliver ? -this._animalCountToDeliver : -itemCountOnPlayer);
      }

      protected override void OnTimedOut()
      {
        this.ApplyFailureEffects(true);
        this.AddLog(this._failByTimeOutQuestLogText);
        TraitLevelingHelper.OnIssueSolvedThroughQuest(this.QuestGiver, new Tuple<TraitObject, int>[1]
        {
          new Tuple<TraitObject, int>(DefaultTraits.Honor, -10)
        });
        this.RemoveRemainingHorses();
      }

      public override void OnFailed()
      {
        this.ApplyFailureEffects();
        this.AddLog(this._failByRejectQuestLogText);
        TraitLevelingHelper.OnIssueSolvedThroughQuest(this.QuestGiver, new Tuple<TraitObject, int>[1]
        {
          new Tuple<TraitObject, int>(DefaultTraits.Honor, -30)
        });
      }

      private void ApplyFailureEffects(bool isTimedOut = false)
      {
        this.QuestGiver.AddPower(-5f);
        this._targetSettlement.Town.Prosperity -= 10f;
        this.RelationshipChangeWithQuestGiver = isTimedOut ? -5 : -10;
      }

      private void RemoveRemainingHorses()
      {
        int animalCountToDeliver = this._animalCountToDeliver;
        foreach (ItemRosterElement itemRosterElement in MobileParty.MainParty.ItemRoster)
        {
          if (itemRosterElement.EquipmentElement.Item == this._herdTypeToDeliver)
          {
            int amount = itemRosterElement.Amount;
            if (amount < animalCountToDeliver)
            {
              animalCountToDeliver -= amount;
              PartyBase.MainParty.ItemRoster.AddToCounts(itemRosterElement.EquipmentElement, -amount);
            }
            else
            {
              PartyBase.MainParty.ItemRoster.AddToCounts(itemRosterElement.EquipmentElement, -animalCountToDeliver);
              break;
            }
          }
        }
      }

      private void AddHerdAndShepherdsToMainParty()
      {
        MobileParty.MainParty.ItemRoster.AddToCounts(this._herdTypeToDeliver, this._animalCountToDeliver);
        MobileParty.MainParty.ItemRoster.AddToCounts(DefaultItems.Grain, 5);
        TextObject message = new TextObject("{=GgBtpOEm}{.%}{ANIMAL_COUNT} {?ANIMAL_COUNT > 1}{PLURAL(ANIMAL_TYPE)}{?}{ANIMAL_TYPE}{\\?}{.%} added to your party.");
        message.SetTextVariable("ANIMAL_COUNT", this._animalCountToDeliver);
        message.SetTextVariable("ANIMAL_TYPE", this._herdTypeToDeliver.Name);
        MBInformationManager.AddQuickInformation(message);
      }

      protected override void InitializeQuestOnGameLoad()
      {
        this.SetDialogs();
        Campaign.Current.ConversationManager.AddDialogFlow(this.GetDeliveryDialogFlow(), (object) this);
      }

      protected override void HourlyTick()
      {
      }

      protected override void RegisterEvents()
      {
        CampaignEvents.HeroKilledEvent.AddNonSerializedListener((object) this, new Action<Hero, Hero, KillCharacterAction.KillCharacterActionDetail, bool>(this.OnHeroKilled));
        CampaignEvents.WarDeclared.AddNonSerializedListener((object) this, new Action<IFaction, IFaction, DeclareWarAction.DeclareWarDetail>(this.OnWarDeclared));
        CampaignEvents.OnClanChangedKingdomEvent.AddNonSerializedListener((object) this, new Action<Clan, Kingdom, Kingdom, ChangeKingdomAction.ChangeKingdomActionDetail, bool>(this.OnClanChangedKingdom));
        CampaignEvents.MapEventStarted.AddNonSerializedListener((object) this, new Action<MapEvent, PartyBase, PartyBase>(this.OnMapEventStarted));
      }

      public override void OnHeroCanHaveQuestOrIssueInfoIsRequested(Hero hero, ref bool result)
      {
        if (hero != this._targetHero)
          return;
        result = false;
      }

      private void OnMapEventStarted(
        MapEvent mapEvent,
        PartyBase attackerParty,
        PartyBase defenderParty)
      {
        if (!QuestHelper.CheckMinorMajorCoercion((QuestBase) this, mapEvent, attackerParty))
          return;
        QuestHelper.ApplyGenericMinorMajorCoercionConsequences((QuestBase) this, mapEvent);
      }

      protected override TextObject TargetHeroDiedLogText
      {
        get
        {
          return new TextObject("{=m41vdhSR}{QUEST_TARGET.LINK} is no longer alive. It might not be your fault that you didn't get the herd to {?QUEST_TARGET.GENDER}her{?}him{\\?} in time, but many people will consider this breach of trust.");
        }
      }

      private void OnHeroKilled(
        Hero victim,
        Hero killer,
        KillCharacterAction.KillCharacterActionDetail detail,
        bool showNotification)
      {
        if (victim != this._targetHero)
          return;
        TextObject textObject = detail == KillCharacterAction.KillCharacterActionDetail.Lost ? this.TargetHeroDisappearedLogText : this.TargetHeroDiedLogText;
        StringHelpers.SetCharacterProperties("QUEST_TARGET", this._targetHero.CharacterObject, textObject);
        StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, textObject);
        this.AddLog(textObject);
        this.CompleteQuestWithCancel();
      }

      private void OnClanChangedKingdom(
        Clan clan,
        Kingdom oldKingdom,
        Kingdom newKingdom,
        ChangeKingdomAction.ChangeKingdomActionDetail detail,
        bool showNotification = true)
      {
        if (!this.QuestGiver.CurrentSettlement.MapFaction.IsAtWarWith(Hero.MainHero.MapFaction))
          return;
        this.CompleteQuestWithCancel(this._questCanceledWarDeclaredLog);
      }

      private void OnWarDeclared(
        IFaction faction1,
        IFaction faction2,
        DeclareWarAction.DeclareWarDetail detail)
      {
        QuestHelper.CheckWarDeclarationAndFailOrCancelTheQuest((QuestBase) this, faction1, faction2, detail, this._playerDeclaredWarQuestLogText, this._questCanceledWarDeclaredLog);
      }
    }

    public class HeadmanNeedsToDeliverAHerdIssueTypeDefiner : SaveableTypeDefiner
    {
      public HeadmanNeedsToDeliverAHerdIssueTypeDefiner()
        : base(430000)
      {
      }

      protected override void DefineClassTypes()
      {
        this.AddClassDefinition(typeof (HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssue), 1);
        this.AddClassDefinition(typeof (HeadmanNeedsToDeliverAHerdIssueBehavior.HeadmanNeedsToDeliverAHerdIssueQuest), 2);
      }
    }
  }
}
